"""
行为轨迹分析系统
实现人员轨迹的跟踪和记录，异常行为模式的分析和预测，当事人身份的关联和管理
"""
import asyncio
import logging
import numpy as np
from datetime import datetime, timedelta
from typing import List, Dict, Optional, Tuple, Any, Set
from uuid import uuid4
import time
from collections import defaultdict, deque
from dataclasses import dataclass, field
from enum import Enum
import json
import math
from sklearn.cluster import DBSCAN
from sklearn.preprocessing import StandardScaler

from schemas.pose_detection import PoseEstimation, ActionRecognition, BehaviorSeverity
from schemas.person_detection import PersonDetectionResult
from core.config import get_settings

logger = logging.getLogger(__name__)
settings = get_settings()


class TrajectoryType(str, Enum):
    """轨迹类型枚举"""
    NORMAL = "normal"
    SUSPICIOUS = "suspicious"
    LOITERING = "loitering"
    ERRATIC = "erratic"
    AGGRESSIVE = "aggressive"
    ESCAPE = "escape"
    FOLLOWING = "following"
    CIRCLING = "circling"


class IdentityStatus(str, Enum):
    """身份状态枚举"""
    UNKNOWN = "unknown"
    IDENTIFIED = "identified"
    SUSPECTED = "suspected"
    CONFIRMED = "confirmed"
    BLACKLISTED = "blacklisted"


class BehaviorPattern(str, Enum):
    """行为模式枚举"""
    REGULAR_VISITOR = "regular_visitor"
    FIRST_TIME_VISITOR = "first_time_visitor"
    FREQUENT_VISITOR = "frequent_visitor"
    SUSPICIOUS_BEHAVIOR = "suspicious_behavior"
    AGGRESSIVE_BEHAVIOR = "aggressive_behavior"
    AVOIDANCE_BEHAVIOR = "avoidance_behavior"


@dataclass
class TrajectoryPoint:
    """轨迹点"""
    timestamp: datetime
    position: Tuple[float, float]
    velocity: Optional[Tuple[float, float]] = None
    acceleration: Optional[Tuple[float, float]] = None
    pose_confidence: float = 0.0
    action_type: Optional[str] = None
    zone_id: Optional[str] = None
    camera_id: Optional[str] = None


@dataclass
class PersonTrajectory:
    """人员轨迹"""
    trajectory_id: str
    person_id: str
    start_time: datetime
    end_time: Optional[datetime]
    points: deque
    trajectory_type: TrajectoryType
    total_distance: float = 0.0
    average_speed: float = 0.0
    max_speed: float = 0.0
    direction_changes: int = 0
    zones_visited: Set[str] = field(default_factory=set)
    cameras_seen: Set[str] = field(default_factory=set)
    duration: float = 0.0
    is_active: bool = True
    confidence: float = 0.0
    
    def __post_init__(self):
        if not isinstance(self.points, deque):
            self.points = deque(maxlen=1000)  # 保持最近1000个点


@dataclass
class PersonIdentity:
    """人员身份"""
    identity_id: str
    person_id: str
    identity_status: IdentityStatus
    confidence: float
    first_seen: datetime
    last_seen: datetime
    total_appearances: int = 0
    behavior_patterns: List[BehaviorPattern] = field(default_factory=list)
    associated_trajectories: List[str] = field(default_factory=list)
    risk_score: float = 0.0
    attributes: Dict[str, Any] = field(default_factory=dict)
    notes: str = ""


@dataclass
class BehaviorAnalysis:
    """行为分析结果"""
    analysis_id: str
    person_id: str
    trajectory_id: str
    analysis_time: datetime
    behavior_patterns: List[BehaviorPattern]
    anomaly_score: float
    risk_assessment: Dict[str, float]
    predictions: Dict[str, Any]
    confidence: float
    evidence: Dict[str, Any] = field(default_factory=dict)


@dataclass
class SpatialZone:
    """空间区域"""
    zone_id: str
    zone_name: str
    coordinates: List[Tuple[float, float]]
    zone_type: str  # entrance, exit, restricted, public, etc.
    risk_level: float = 0.0
    visitor_count: int = 0
    average_dwell_time: float = 0.0


class TrajectoryAnalyzer:
    """轨迹分析器"""
    
    def __init__(self):
        self.min_points_for_analysis = 10
        self.speed_threshold_suspicious = 100.0  # 像素/秒
        self.direction_change_threshold = 45.0  # 度
        self.loitering_time_threshold = 60.0  # 秒
        self.loitering_distance_threshold = 50.0  # 像素
    
    def analyze_trajectory(self, trajectory: PersonTrajectory) -> Dict[str, Any]:
        """分析轨迹特征"""
        if len(trajectory.points) < self.min_points_for_analysis:
            return {}
        
        points = list(trajectory.points)
        
        # 计算基本统计
        stats = self._calculate_basic_stats(points)
        
        # 分析运动模式
        motion_patterns = self._analyze_motion_patterns(points)
        
        # 检测异常行为
        anomalies = self._detect_anomalies(points, stats)
        
        # 空间分析
        spatial_analysis = self._analyze_spatial_behavior(points)
        
        # 时间分析
        temporal_analysis = self._analyze_temporal_behavior(points)
        
        return {
            'basic_stats': stats,
            'motion_patterns': motion_patterns,
            'anomalies': anomalies,
            'spatial_analysis': spatial_analysis,
            'temporal_analysis': temporal_analysis
        }
    
    def _calculate_basic_stats(self, points: List[TrajectoryPoint]) -> Dict[str, float]:
        """计算基本统计信息"""
        if len(points) < 2:
            return {}
        
        # 计算距离和速度
        distances = []
        speeds = []
        
        for i in range(1, len(points)):
            prev_point = points[i-1]
            curr_point = points[i]
            
            # 计算距离
            dx = curr_point.position[0] - prev_point.position[0]
            dy = curr_point.position[1] - prev_point.position[1]
            distance = math.sqrt(dx*dx + dy*dy)
            distances.append(distance)
            
            # 计算速度
            dt = (curr_point.timestamp - prev_point.timestamp).total_seconds()
            if dt > 0:
                speed = distance / dt
                speeds.append(speed)
        
        # 计算方向变化
        direction_changes = self._count_direction_changes(points)
        
        return {
            'total_distance': sum(distances),
            'average_speed': np.mean(speeds) if speeds else 0,
            'max_speed': np.max(speeds) if speeds else 0,
            'min_speed': np.min(speeds) if speeds else 0,
            'speed_variance': np.var(speeds) if speeds else 0,
            'direction_changes': direction_changes,
            'duration': (points[-1].timestamp - points[0].timestamp).total_seconds()
        }
    
    def _count_direction_changes(self, points: List[TrajectoryPoint]) -> int:
        """计算方向变化次数"""
        if len(points) < 3:
            return 0
        
        direction_changes = 0
        prev_direction = None
        
        for i in range(1, len(points)):
            prev_point = points[i-1]
            curr_point = points[i]
            
            dx = curr_point.position[0] - prev_point.position[0]
            dy = curr_point.position[1] - prev_point.position[1]
            
            if dx != 0 or dy != 0:
                direction = math.atan2(dy, dx)
                
                if prev_direction is not None:
                    angle_diff = abs(direction - prev_direction)
                    if angle_diff > math.pi:
                        angle_diff = 2 * math.pi - angle_diff
                    
                    if math.degrees(angle_diff) > self.direction_change_threshold:
                        direction_changes += 1
                
                prev_direction = direction
        
        return direction_changes
    
    def _analyze_motion_patterns(self, points: List[TrajectoryPoint]) -> Dict[str, Any]:
        """分析运动模式"""
        patterns = {}
        
        if len(points) < 5:
            return patterns
        
        # 检测徘徊行为
        patterns['loitering'] = self._detect_loitering(points)
        
        # 检测圆形运动
        patterns['circling'] = self._detect_circling(points)
        
        # 检测直线运动
        patterns['linear_movement'] = self._detect_linear_movement(points)
        
        # 检测停止行为
        patterns['stops'] = self._detect_stops(points)
        
        # 检测加速/减速
        patterns['acceleration_patterns'] = self._analyze_acceleration(points)
        
        return patterns
    
    def _detect_loitering(self, points: List[TrajectoryPoint]) -> Dict[str, Any]:
        """检测徘徊行为"""
        if len(points) < 10:
            return {'detected': False}
        
        # 计算位置方差
        positions = [p.position for p in points]
        x_coords = [p[0] for p in positions]
        y_coords = [p[1] for p in positions]
        
        x_var = np.var(x_coords)
        y_var = np.var(y_coords)
        position_variance = math.sqrt(x_var + y_var)
        
        # 计算时间跨度
        duration = (points[-1].timestamp - points[0].timestamp).total_seconds()
        
        # 判断是否为徘徊
        is_loitering = (position_variance < self.loitering_distance_threshold and 
                       duration > self.loitering_time_threshold)
        
        return {
            'detected': is_loitering,
            'position_variance': position_variance,
            'duration': duration,
            'center': (np.mean(x_coords), np.mean(y_coords))
        }
    
    def _detect_circling(self, points: List[TrajectoryPoint]) -> Dict[str, Any]:
        """检测圆形运动"""
        if len(points) < 20:
            return {'detected': False}
        
        positions = [p.position for p in points]
        
        # 计算中心点
        center_x = np.mean([p[0] for p in positions])
        center_y = np.mean([p[1] for p in positions])
        center = (center_x, center_y)
        
        # 计算到中心的距离
        distances = [math.sqrt((p[0] - center_x)**2 + (p[1] - center_y)**2) for p in positions]
        
        # 计算角度变化
        angles = []
        for pos in positions:
            angle = math.atan2(pos[1] - center_y, pos[0] - center_x)
            angles.append(angle)
        
        # 检查是否形成圆形
        distance_variance = np.var(distances)
        mean_distance = np.mean(distances)
        
        # 计算总角度变化
        total_angle_change = 0
        for i in range(1, len(angles)):
            angle_diff = angles[i] - angles[i-1]
            if angle_diff > math.pi:
                angle_diff -= 2 * math.pi
            elif angle_diff < -math.pi:
                angle_diff += 2 * math.pi
            total_angle_change += abs(angle_diff)
        
        # 判断是否为圆形运动
        is_circling = (distance_variance < mean_distance * 0.3 and 
                      total_angle_change > math.pi)  # 至少半圈
        
        return {
            'detected': is_circling,
            'center': center,
            'average_radius': mean_distance,
            'radius_variance': distance_variance,
            'total_angle_change': total_angle_change
        }
    
    def _detect_linear_movement(self, points: List[TrajectoryPoint]) -> Dict[str, Any]:
        """检测直线运动"""
        if len(points) < 5:
            return {'detected': False}
        
        positions = [p.position for p in points]
        
        # 使用线性回归拟合直线
        x_coords = np.array([p[0] for p in positions])
        y_coords = np.array([p[1] for p in positions])
        
        # 计算相关系数
        correlation = np.corrcoef(x_coords, y_coords)[0, 1] if len(set(x_coords)) > 1 else 0
        
        # 计算到拟合直线的平均距离
        if len(positions) > 2:
            # 简化的直线拟合
            start_pos = positions[0]
            end_pos = positions[-1]
            
            distances_to_line = []
            for pos in positions[1:-1]:
                distance = self._point_to_line_distance(pos, start_pos, end_pos)
                distances_to_line.append(distance)
            
            avg_deviation = np.mean(distances_to_line) if distances_to_line else 0
        else:
            avg_deviation = 0
        
        is_linear = abs(correlation) > 0.8 and avg_deviation < 50
        
        return {
            'detected': is_linear,
            'correlation': correlation,
            'average_deviation': avg_deviation,
            'start_position': positions[0],
            'end_position': positions[-1]
        }
    
    def _point_to_line_distance(self, point: Tuple[float, float], 
                               line_start: Tuple[float, float], 
                               line_end: Tuple[float, float]) -> float:
        """计算点到直线的距离"""
        x0, y0 = point
        x1, y1 = line_start
        x2, y2 = line_end
        
        # 直线方程: (y2-y1)x - (x2-x1)y + (x2-x1)y1 - (y2-y1)x1 = 0
        A = y2 - y1
        B = x1 - x2
        C = (x2 - x1) * y1 - (y2 - y1) * x1
        
        # 点到直线距离公式
        distance = abs(A * x0 + B * y0 + C) / math.sqrt(A*A + B*B) if A*A + B*B > 0 else 0
        
        return distance
    
    def _detect_stops(self, points: List[TrajectoryPoint]) -> List[Dict[str, Any]]:
        """检测停止行为"""
        stops = []
        
        if len(points) < 5:
            return stops
        
        current_stop = None
        stop_threshold = 10.0  # 像素
        min_stop_duration = 3.0  # 秒
        
        for i in range(1, len(points)):
            prev_point = points[i-1]
            curr_point = points[i]
            
            distance = math.sqrt(
                (curr_point.position[0] - prev_point.position[0])**2 +
                (curr_point.position[1] - prev_point.position[1])**2
            )
            
            if distance < stop_threshold:
                if current_stop is None:
                    current_stop = {
                        'start_time': prev_point.timestamp,
                        'start_position': prev_point.position,
                        'points': [prev_point, curr_point]
                    }
                else:
                    current_stop['points'].append(curr_point)
            else:
                if current_stop is not None:
                    duration = (current_stop['points'][-1].timestamp - current_stop['start_time']).total_seconds()
                    if duration >= min_stop_duration:
                        # 计算停止区域中心
                        positions = [p.position for p in current_stop['points']]
                        center_x = np.mean([p[0] for p in positions])
                        center_y = np.mean([p[1] for p in positions])
                        
                        stops.append({
                            'start_time': current_stop['start_time'],
                            'end_time': current_stop['points'][-1].timestamp,
                            'duration': duration,
                            'center_position': (center_x, center_y),
                            'point_count': len(current_stop['points'])
                        })
                    
                    current_stop = None
        
        return stops
    
    def _analyze_acceleration(self, points: List[TrajectoryPoint]) -> Dict[str, Any]:
        """分析加速度模式"""
        if len(points) < 3:
            return {}
        
        accelerations = []
        
        for i in range(2, len(points)):
            p1, p2, p3 = points[i-2], points[i-1], points[i]
            
            # 计算速度
            dt1 = (p2.timestamp - p1.timestamp).total_seconds()
            dt2 = (p3.timestamp - p2.timestamp).total_seconds()
            
            if dt1 > 0 and dt2 > 0:
                v1 = math.sqrt((p2.position[0] - p1.position[0])**2 + (p2.position[1] - p1.position[1])**2) / dt1
                v2 = math.sqrt((p3.position[0] - p2.position[0])**2 + (p3.position[1] - p2.position[1])**2) / dt2
                
                # 计算加速度
                acceleration = (v2 - v1) / dt2
                accelerations.append(acceleration)
        
        if not accelerations:
            return {}
        
        return {
            'average_acceleration': np.mean(accelerations),
            'max_acceleration': np.max(accelerations),
            'min_acceleration': np.min(accelerations),
            'acceleration_variance': np.var(accelerations)
        }
    
    def _detect_anomalies(self, points: List[TrajectoryPoint], stats: Dict[str, float]) -> List[str]:
        """检测异常行为"""
        anomalies = []
        
        # 速度异常
        if stats.get('max_speed', 0) > self.speed_threshold_suspicious:
            anomalies.append('high_speed')
        
        # 方向变化异常
        if stats.get('direction_changes', 0) > len(points) * 0.3:
            anomalies.append('erratic_movement')
        
        # 徘徊异常
        if stats.get('duration', 0) > self.loitering_time_threshold:
            total_distance = stats.get('total_distance', 0)
            if total_distance < 100:  # 长时间但移动距离很短
                anomalies.append('loitering')
        
        return anomalies
    
    def _analyze_spatial_behavior(self, points: List[TrajectoryPoint]) -> Dict[str, Any]:
        """分析空间行为"""
        if not points:
            return {}
        
        positions = [p.position for p in points]
        
        # 计算活动范围
        x_coords = [p[0] for p in positions]
        y_coords = [p[1] for p in positions]
        
        activity_area = {
            'min_x': min(x_coords),
            'max_x': max(x_coords),
            'min_y': min(y_coords),
            'max_y': max(y_coords),
            'width': max(x_coords) - min(x_coords),
            'height': max(y_coords) - min(y_coords)
        }
        
        # 计算访问的区域
        zones_visited = set()
        for point in points:
            if point.zone_id:
                zones_visited.add(point.zone_id)
        
        return {
            'activity_area': activity_area,
            'zones_visited': list(zones_visited),
            'zone_count': len(zones_visited)
        }
    
    def _analyze_temporal_behavior(self, points: List[TrajectoryPoint]) -> Dict[str, Any]:
        """分析时间行为"""
        if not points:
            return {}
        
        start_time = points[0].timestamp
        end_time = points[-1].timestamp
        duration = (end_time - start_time).total_seconds()
        
        # 分析活动时间段
        hours = [p.timestamp.hour for p in points]
        hour_distribution = {}
        for hour in hours:
            hour_distribution[hour] = hour_distribution.get(hour, 0) + 1
        
        # 计算活动密度
        if duration > 0:
            activity_density = len(points) / duration  # 点/秒
        else:
            activity_density = 0
        
        return {
            'start_time': start_time,
            'end_time': end_time,
            'duration': duration,
            'hour_distribution': hour_distribution,
            'activity_density': activity_density,
            'most_active_hour': max(hour_distribution.items(), key=lambda x: x[1])[0] if hour_distribution else None
        }


class IdentityManager:
    """身份管理器"""
    
    def __init__(self):
        self.identities: Dict[str, PersonIdentity] = {}
        self.person_to_identity: Dict[str, str] = {}  # person_id -> identity_id
        self.similarity_threshold = 0.8
        self.risk_factors = {
            'frequent_visits': 0.1,
            'suspicious_behavior': 0.3,
            'aggressive_behavior': 0.5,
            'restricted_area_access': 0.4,
            'unusual_timing': 0.2
        }
    
    def get_or_create_identity(self, person_id: str) -> PersonIdentity:
        """获取或创建身份"""
        if person_id in self.person_to_identity:
            identity_id = self.person_to_identity[person_id]
            return self.identities[identity_id]
        
        # 创建新身份
        identity_id = str(uuid4())
        identity = PersonIdentity(
            identity_id=identity_id,
            person_id=person_id,
            identity_status=IdentityStatus.UNKNOWN,
            confidence=0.5,
            first_seen=datetime.now(),
            last_seen=datetime.now()
        )
        
        self.identities[identity_id] = identity
        self.person_to_identity[person_id] = identity_id
        
        return identity
    
    def update_identity(self, person_id: str, trajectory: PersonTrajectory, behavior_analysis: BehaviorAnalysis):
        """更新身份信息"""
        identity = self.get_or_create_identity(person_id)
        
        # 更新基本信息
        identity.last_seen = datetime.now()
        identity.total_appearances += 1
        identity.associated_trajectories.append(trajectory.trajectory_id)
        
        # 分析行为模式
        new_patterns = self._analyze_behavior_patterns(trajectory, behavior_analysis)
        for pattern in new_patterns:
            if pattern not in identity.behavior_patterns:
                identity.behavior_patterns.append(pattern)
        
        # 更新风险评分
        identity.risk_score = self._calculate_risk_score(identity, behavior_analysis)
        
        # 更新身份状态
        identity.identity_status = self._determine_identity_status(identity)
        
        # 保持最近100个轨迹
        if len(identity.associated_trajectories) > 100:
            identity.associated_trajectories = identity.associated_trajectories[-100:]
    
    def _analyze_behavior_patterns(self, trajectory: PersonTrajectory, behavior_analysis: BehaviorAnalysis) -> List[BehaviorPattern]:
        """分析行为模式"""
        patterns = []
        
        # 基于访问频率
        if trajectory.duration > 3600:  # 超过1小时
            patterns.append(BehaviorPattern.FREQUENT_VISITOR)
        elif trajectory.duration < 300:  # 少于5分钟
            patterns.append(BehaviorPattern.FIRST_TIME_VISITOR)
        else:
            patterns.append(BehaviorPattern.REGULAR_VISITOR)
        
        # 基于行为分析
        if behavior_analysis.anomaly_score > 0.7:
            patterns.append(BehaviorPattern.SUSPICIOUS_BEHAVIOR)
        
        if 'aggressive' in behavior_analysis.behavior_patterns:
            patterns.append(BehaviorPattern.AGGRESSIVE_BEHAVIOR)
        
        # 基于轨迹类型
        if trajectory.trajectory_type in [TrajectoryType.SUSPICIOUS, TrajectoryType.ERRATIC]:
            patterns.append(BehaviorPattern.SUSPICIOUS_BEHAVIOR)
        
        return patterns
    
    def _calculate_risk_score(self, identity: PersonIdentity, behavior_analysis: BehaviorAnalysis) -> float:
        """计算风险评分"""
        risk_score = 0.0
        
        # 基于行为模式
        for pattern in identity.behavior_patterns:
            if pattern == BehaviorPattern.SUSPICIOUS_BEHAVIOR:
                risk_score += self.risk_factors['suspicious_behavior']
            elif pattern == BehaviorPattern.AGGRESSIVE_BEHAVIOR:
                risk_score += self.risk_factors['aggressive_behavior']
            elif pattern == BehaviorPattern.FREQUENT_VISITOR:
                risk_score += self.risk_factors['frequent_visits']
        
        # 基于异常评分
        risk_score += behavior_analysis.anomaly_score * 0.3
        
        # 基于风险评估
        for risk_type, risk_value in behavior_analysis.risk_assessment.items():
            if risk_type in self.risk_factors:
                risk_score += risk_value * self.risk_factors[risk_type]
        
        return min(1.0, risk_score)
    
    def _determine_identity_status(self, identity: PersonIdentity) -> IdentityStatus:
        """确定身份状态"""
        if identity.risk_score > 0.8:
            return IdentityStatus.BLACKLISTED
        elif identity.risk_score > 0.6:
            return IdentityStatus.SUSPECTED
        elif identity.total_appearances > 10:
            return IdentityStatus.CONFIRMED
        elif identity.total_appearances > 3:
            return IdentityStatus.IDENTIFIED
        else:
            return IdentityStatus.UNKNOWN
    
    def get_identity_by_person_id(self, person_id: str) -> Optional[PersonIdentity]:
        """根据person_id获取身份"""
        if person_id in self.person_to_identity:
            identity_id = self.person_to_identity[person_id]
            return self.identities.get(identity_id)
        return None
    
    def get_all_identities(self) -> List[PersonIdentity]:
        """获取所有身份"""
        return list(self.identities.values())
    
    def get_high_risk_identities(self, threshold: float = 0.6) -> List[PersonIdentity]:
        """获取高风险身份"""
        return [identity for identity in self.identities.values() if identity.risk_score >= threshold]


class TrajectoryAnalysisService:
    """轨迹分析服务"""
    
    def __init__(self):
        self.trajectory_analyzer = TrajectoryAnalyzer()
        self.identity_manager = IdentityManager()
        
        self.trajectories: Dict[str, PersonTrajectory] = {}
        self.behavior_analyses: List[BehaviorAnalysis] = []
        self.spatial_zones: Dict[str, SpatialZone] = {}
        
        # 服务状态
        self._running = False
        self._analysis_task = None
        self.analysis_interval = 5.0  # 5秒分析一次
        
        # 统计信息
        self.stats = {
            'total_trajectories': 0,
            'active_trajectories': 0,
            'completed_trajectories': 0,
            'anomalous_trajectories': 0,
            'total_identities': 0
        }
        
        # 初始化默认区域
        self._initialize_default_zones()
    
    def _initialize_default_zones(self):
        """初始化默认区域"""
        default_zones = [
            SpatialZone(
                zone_id="entrance",
                zone_name="入口区域",
                coordinates=[(0, 0), (200, 0), (200, 150), (0, 150)],
                zone_type="entrance"
            ),
            SpatialZone(
                zone_id="main_area",
                zone_name="主要区域",
                coordinates=[(200, 150), (600, 150), (600, 450), (200, 450)],
                zone_type="public"
            ),
            SpatialZone(
                zone_id="restricted",
                zone_name="限制区域",
                coordinates=[(600, 0), (800, 0), (800, 200), (600, 200)],
                zone_type="restricted",
                risk_level=0.8
            )
        ]
        
        for zone in default_zones:
            self.spatial_zones[zone.zone_id] = zone
    
    async def start_service(self):
        """启动服务"""
        if self._running:
            return
        
        self._running = True
        self._analysis_task = asyncio.create_task(self._analysis_loop())
        logger.info("Trajectory analysis service started")
    
    async def stop_service(self):
        """停止服务"""
        self._running = False
        if self._analysis_task:
            self._analysis_task.cancel()
            try:
                await self._analysis_task
            except asyncio.CancelledError:
                pass
        logger.info("Trajectory analysis service stopped")
    
    async def _analysis_loop(self):
        """分析循环"""
        while self._running:
            try:
                await self._periodic_analysis()
                await asyncio.sleep(self.analysis_interval)
            except asyncio.CancelledError:
                break
            except Exception as e:
                logger.error(f"Error in trajectory analysis loop: {e}")
                await asyncio.sleep(1.0)
    
    async def _periodic_analysis(self):
        """周期性分析"""
        current_time = datetime.now()
        
        # 更新轨迹状态
        for trajectory in self.trajectories.values():
            if trajectory.is_active and trajectory.points:
                last_point = trajectory.points[-1]
                age = (current_time - last_point.timestamp).total_seconds()
                
                if age > 60:  # 1分钟未更新
                    trajectory.is_active = False
                    trajectory.end_time = last_point.timestamp
                    trajectory.duration = (trajectory.end_time - trajectory.start_time).total_seconds()
                    
                    # 执行完整分析
                    await self._analyze_completed_trajectory(trajectory)
        
        # 清理过期轨迹
        expired_trajectories = []
        for trajectory_id, trajectory in self.trajectories.items():
            if not trajectory.is_active and trajectory.end_time:
                age = (current_time - trajectory.end_time).total_seconds()
                if age > 3600:  # 1小时后清理
                    expired_trajectories.append(trajectory_id)
        
        for trajectory_id in expired_trajectories:
            del self.trajectories[trajectory_id]
        
        # 更新统计信息
        self._update_statistics()
    
    async def _analyze_completed_trajectory(self, trajectory: PersonTrajectory):
        """分析完成的轨迹"""
        # 执行轨迹分析
        analysis_result = self.trajectory_analyzer.analyze_trajectory(trajectory)
        
        # 分类轨迹类型
        trajectory.trajectory_type = await self._classify_trajectory_type(trajectory, analysis_result)
        
        # 计算置信度
        trajectory.confidence = await self._calculate_trajectory_confidence(trajectory, analysis_result)
        
        # 创建行为分析
        behavior_analysis = await self._create_behavior_analysis(trajectory, analysis_result)
        self.behavior_analyses.append(behavior_analysis)
        
        # 更新身份信息
        self.identity_manager.update_identity(trajectory.person_id, trajectory, behavior_analysis)
        
        # 更新统计
        self.stats['completed_trajectories'] += 1
        if behavior_analysis.anomaly_score > 0.6:
            self.stats['anomalous_trajectories'] += 1
        
        logger.info(f"Completed trajectory analysis for {trajectory.person_id}: {trajectory.trajectory_type.value}")
    
    async def _classify_trajectory_type(self, trajectory: PersonTrajectory, analysis: Dict[str, Any]) -> TrajectoryType:
        """分类轨迹类型"""
        anomalies = analysis.get('anomalies', [])
        motion_patterns = analysis.get('motion_patterns', {})
        
        # 检查异常行为
        if 'high_speed' in anomalies:
            return TrajectoryType.ESCAPE
        
        if 'erratic_movement' in anomalies:
            return TrajectoryType.ERRATIC
        
        if 'loitering' in anomalies or motion_patterns.get('loitering', {}).get('detected', False):
            return TrajectoryType.LOITERING
        
        # 检查圆形运动
        if motion_patterns.get('circling', {}).get('detected', False):
            return TrajectoryType.CIRCLING
        
        # 检查跟随行为（需要多轨迹分析）
        if await self._detect_following_behavior(trajectory):
            return TrajectoryType.FOLLOWING
        
        # 检查可疑行为
        if len(anomalies) > 0 or trajectory.direction_changes > len(trajectory.points) * 0.2:
            return TrajectoryType.SUSPICIOUS
        
        return TrajectoryType.NORMAL
    
    async def _detect_following_behavior(self, trajectory: PersonTrajectory) -> bool:
        """检测跟随行为"""
        # 简化的跟随检测：查找时间和空间上相近的其他轨迹
        for other_trajectory in self.trajectories.values():
            if (other_trajectory.trajectory_id != trajectory.trajectory_id and
                other_trajectory.person_id != trajectory.person_id):
                
                similarity = await self._calculate_trajectory_similarity(trajectory, other_trajectory)
                if similarity > 0.7:
                    return True
        
        return False
    
    async def _calculate_trajectory_similarity(self, traj1: PersonTrajectory, traj2: PersonTrajectory) -> float:
        """计算轨迹相似度"""
        if not traj1.points or not traj2.points:
            return 0.0
        
        # 时间重叠检查
        time_overlap = self._calculate_time_overlap(traj1, traj2)
        if time_overlap < 0.3:  # 时间重叠少于30%
            return 0.0
        
        # 空间相似度检查
        spatial_similarity = self._calculate_spatial_similarity(traj1, traj2)
        
        return (time_overlap + spatial_similarity) / 2
    
    def _calculate_time_overlap(self, traj1: PersonTrajectory, traj2: PersonTrajectory) -> float:
        """计算时间重叠度"""
        start1, end1 = traj1.start_time, traj1.end_time or datetime.now()
        start2, end2 = traj2.start_time, traj2.end_time or datetime.now()
        
        overlap_start = max(start1, start2)
        overlap_end = min(end1, end2)
        
        if overlap_start >= overlap_end:
            return 0.0
        
        overlap_duration = (overlap_end - overlap_start).total_seconds()
        total_duration = max((end1 - start1).total_seconds(), (end2 - start2).total_seconds())
        
        return overlap_duration / total_duration if total_duration > 0 else 0.0
    
    def _calculate_spatial_similarity(self, traj1: PersonTrajectory, traj2: PersonTrajectory) -> float:
        """计算空间相似度"""
        points1 = list(traj1.points)
        points2 = list(traj2.points)
        
        if not points1 or not points2:
            return 0.0
        
        # 计算平均距离
        total_distance = 0
        count = 0
        
        for p1 in points1:
            min_distance = float('inf')
            for p2 in points2:
                distance = math.sqrt(
                    (p1.position[0] - p2.position[0])**2 +
                    (p1.position[1] - p2.position[1])**2
                )
                min_distance = min(min_distance, distance)
            
            total_distance += min_distance
            count += 1
        
        avg_distance = total_distance / count if count > 0 else float('inf')
        
        # 转换为相似度（距离越小相似度越高）
        similarity = max(0, 1 - avg_distance / 200)  # 200像素为最大有效距离
        
        return similarity
    
    async def _calculate_trajectory_confidence(self, trajectory: PersonTrajectory, analysis: Dict[str, Any]) -> float:
        """计算轨迹置信度"""
        confidence_factors = []
        
        # 基于点数量
        point_count_factor = min(1.0, len(trajectory.points) / 50)
        confidence_factors.append(point_count_factor)
        
        # 基于持续时间
        duration_factor = min(1.0, trajectory.duration / 300)  # 5分钟为满分
        confidence_factors.append(duration_factor)
        
        # 基于姿态置信度
        if trajectory.points:
            pose_confidences = [p.pose_confidence for p in trajectory.points if p.pose_confidence > 0]
            avg_pose_confidence = np.mean(pose_confidences) if pose_confidences else 0.5
            confidence_factors.append(avg_pose_confidence)
        
        # 基于分析结果的一致性
        analysis_consistency = 1.0 - len(analysis.get('anomalies', [])) * 0.1
        confidence_factors.append(max(0, analysis_consistency))
        
        return np.mean(confidence_factors)
    
    async def _create_behavior_analysis(self, trajectory: PersonTrajectory, analysis_result: Dict[str, Any]) -> BehaviorAnalysis:
        """创建行为分析"""
        # 确定行为模式
        behavior_patterns = []
        if trajectory.trajectory_type == TrajectoryType.SUSPICIOUS:
            behavior_patterns.append(BehaviorPattern.SUSPICIOUS_BEHAVIOR)
        elif trajectory.trajectory_type == TrajectoryType.AGGRESSIVE:
            behavior_patterns.append(BehaviorPattern.AGGRESSIVE_BEHAVIOR)
        else:
            behavior_patterns.append(BehaviorPattern.REGULAR_VISITOR)
        
        # 计算异常评分
        anomaly_score = len(analysis_result.get('anomalies', [])) * 0.2
        anomaly_score = min(1.0, anomaly_score)
        
        # 风险评估
        risk_assessment = {
            'movement_risk': anomaly_score,
            'temporal_risk': 0.1 if trajectory.duration > 3600 else 0.0,
            'spatial_risk': 0.3 if any(zone.risk_level > 0.5 for zone in self.spatial_zones.values() if zone.zone_id in trajectory.zones_visited) else 0.0
        }
        
        # 预测
        predictions = {
            'likely_next_zone': self._predict_next_zone(trajectory),
            'estimated_stay_duration': self._predict_stay_duration(trajectory),
            'risk_escalation_probability': min(1.0, anomaly_score + 0.2)
        }
        
        return BehaviorAnalysis(
            analysis_id=str(uuid4()),
            person_id=trajectory.person_id,
            trajectory_id=trajectory.trajectory_id,
            analysis_time=datetime.now(),
            behavior_patterns=behavior_patterns,
            anomaly_score=anomaly_score,
            risk_assessment=risk_assessment,
            predictions=predictions,
            confidence=trajectory.confidence,
            evidence=analysis_result
        )
    
    def _predict_next_zone(self, trajectory: PersonTrajectory) -> Optional[str]:
        """预测下一个区域"""
        if not trajectory.points or len(trajectory.points) < 3:
            return None
        
        # 基于最近的移动方向预测
        recent_points = list(trajectory.points)[-3:]
        
        # 计算移动方向
        dx = recent_points[-1].position[0] - recent_points[0].position[0]
        dy = recent_points[-1].position[1] - recent_points[0].position[1]
        
        # 预测下一个位置
        next_x = recent_points[-1].position[0] + dx
        next_y = recent_points[-1].position[1] + dy
        
        # 查找包含预测位置的区域
        for zone in self.spatial_zones.values():
            if self._point_in_polygon((next_x, next_y), zone.coordinates):
                return zone.zone_id
        
        return None
    
    def _point_in_polygon(self, point: Tuple[float, float], polygon: List[Tuple[float, float]]) -> bool:
        """判断点是否在多边形内"""
        x, y = point
        n = len(polygon)
        inside = False
        
        p1x, p1y = polygon[0]
        for i in range(1, n + 1):
            p2x, p2y = polygon[i % n]
            if y > min(p1y, p2y):
                if y <= max(p1y, p2y):
                    if x <= max(p1x, p2x):
                        if p1y != p2y:
                            xinters = (y - p1y) * (p2x - p1x) / (p2y - p1y) + p1x
                        if p1x == p2x or x <= xinters:
                            inside = not inside
            p1x, p1y = p2x, p2y
        
        return inside
    
    def _predict_stay_duration(self, trajectory: PersonTrajectory) -> float:
        """预测停留时间"""
        # 基于历史平均停留时间
        if trajectory.duration > 0:
            return trajectory.duration * 1.2  # 预测比当前时间多20%
        
        return 300.0  # 默认5分钟
    
    def _update_statistics(self):
        """更新统计信息"""
        self.stats['total_trajectories'] = len(self.trajectories)
        self.stats['active_trajectories'] = len([t for t in self.trajectories.values() if t.is_active])
        self.stats['total_identities'] = len(self.identity_manager.identities)
    
    async def update_trajectory(self, person_id: str, pose: PoseEstimation, camera_id: str):
        """更新轨迹"""
        # 查找或创建轨迹
        trajectory = None
        for traj in self.trajectories.values():
            if traj.person_id == person_id and traj.is_active:
                trajectory = traj
                break
        
        if trajectory is None:
            trajectory_id = str(uuid4())
            trajectory = PersonTrajectory(
                trajectory_id=trajectory_id,
                person_id=person_id,
                start_time=datetime.now(),
                points=deque(maxlen=1000),
                trajectory_type=TrajectoryType.NORMAL
            )
            self.trajectories[trajectory_id] = trajectory
            self.stats['total_trajectories'] += 1
        
        # 创建轨迹点
        center = pose.get_center_point()
        zone_id = self._get_zone_for_position(center)
        
        trajectory_point = TrajectoryPoint(
            timestamp=datetime.now(),
            position=center,
            pose_confidence=pose.pose_confidence,
            zone_id=zone_id,
            camera_id=camera_id
        )
        
        # 计算速度和加速度
        if trajectory.points:
            last_point = trajectory.points[-1]
            dt = (trajectory_point.timestamp - last_point.timestamp).total_seconds()
            
            if dt > 0:
                dx = trajectory_point.position[0] - last_point.position[0]
                dy = trajectory_point.position[1] - last_point.position[1]
                velocity = (dx / dt, dy / dt)
                trajectory_point.velocity = velocity
                
                # 计算加速度
                if last_point.velocity:
                    ax = (velocity[0] - last_point.velocity[0]) / dt
                    ay = (velocity[1] - last_point.velocity[1]) / dt
                    trajectory_point.acceleration = (ax, ay)
        
        # 添加点到轨迹
        trajectory.points.append(trajectory_point)
        
        # 更新轨迹信息
        if zone_id:
            trajectory.zones_visited.add(zone_id)
        trajectory.cameras_seen.add(camera_id)
        
        # 计算总距离
        if len(trajectory.points) >= 2:
            last_two_points = list(trajectory.points)[-2:]
            distance = math.sqrt(
                (last_two_points[1].position[0] - last_two_points[0].position[0])**2 +
                (last_two_points[1].position[1] - last_two_points[0].position[1])**2
            )
            trajectory.total_distance += distance
        
        # 更新速度统计
        if trajectory_point.velocity:
            speed = math.sqrt(trajectory_point.velocity[0]**2 + trajectory_point.velocity[1]**2)
            trajectory.max_speed = max(trajectory.max_speed, speed)
            
            # 计算平均速度
            speeds = []
            for point in trajectory.points:
                if point.velocity:
                    point_speed = math.sqrt(point.velocity[0]**2 + point.velocity[1]**2)
                    speeds.append(point_speed)
            
            if speeds:
                trajectory.average_speed = np.mean(speeds)
    
    def _get_zone_for_position(self, position: Tuple[float, float]) -> Optional[str]:
        """获取位置所在的区域"""
        for zone in self.spatial_zones.values():
            if self._point_in_polygon(position, zone.coordinates):
                return zone.zone_id
        return None
    
    async def get_trajectories(
        self,
        person_id: Optional[str] = None,
        trajectory_type: Optional[TrajectoryType] = None,
        is_active: Optional[bool] = None,
        start_time: Optional[datetime] = None,
        end_time: Optional[datetime] = None,
        limit: int = 100
    ) -> List[PersonTrajectory]:
        """获取轨迹"""
        trajectories = list(self.trajectories.values())
        
        # 过滤条件
        if person_id:
            trajectories = [t for t in trajectories if t.person_id == person_id]
        
        if trajectory_type:
            trajectories = [t for t in trajectories if t.trajectory_type == trajectory_type]
        
        if is_active is not None:
            trajectories = [t for t in trajectories if t.is_active == is_active]
        
        if start_time:
            trajectories = [t for t in trajectories if t.start_time >= start_time]
        
        if end_time:
            trajectories = [t for t in trajectories if t.start_time <= end_time]
        
        # 按开始时间倒序排列
        trajectories.sort(key=lambda x: x.start_time, reverse=True)
        
        return trajectories[:limit]
    
    async def get_behavior_analyses(
        self,
        person_id: Optional[str] = None,
        limit: int = 100
    ) -> List[BehaviorAnalysis]:
        """获取行为分析"""
        analyses = self.behavior_analyses
        
        if person_id:
            analyses = [a for a in analyses if a.person_id == person_id]
        
        # 按分析时间倒序排列
        analyses.sort(key=lambda x: x.analysis_time, reverse=True)
        
        return analyses[:limit]
    
    def get_identities(
        self,
        identity_status: Optional[IdentityStatus] = None,
        min_risk_score: Optional[float] = None
    ) -> List[PersonIdentity]:
        """获取身份信息"""
        identities = self.identity_manager.get_all_identities()
        
        if identity_status:
            identities = [i for i in identities if i.identity_status == identity_status]
        
        if min_risk_score is not None:
            identities = [i for i in identities if i.risk_score >= min_risk_score]
        
        # 按风险评分倒序排列
        identities.sort(key=lambda x: x.risk_score, reverse=True)
        
        return identities
    
    def get_statistics(self) -> Dict[str, Any]:
        """获取统计信息"""
        return self.stats.copy()
    
    def add_spatial_zone(self, zone: SpatialZone):
        """添加空间区域"""
        self.spatial_zones[zone.zone_id] = zone
        logger.info(f"Added spatial zone: {zone.zone_id}")
    
    def get_spatial_zones(self) -> List[SpatialZone]:
        """获取空间区域"""
        return list(self.spatial_zones.values())


# 全局轨迹分析服务实例
trajectory_analysis_service = TrajectoryAnalysisService()